=begin pod :tag<convert>

=TITLE Perl 6 from Ruby - Nutshell

=SUBTITLE Learning Perl 6 from Ruby, in a nutshell: What do I already know?

This page attempts to index the high-level differences in syntax and semantics
between Ruby and Perl 6. Whatever works in Ruby and must be written differently
in Perl 6 should be listed here (whereas many Perl 6 features and idioms won't
be).

Hence this should not be mistaken for a beginner tutorial or overview of Perl
6; it is intended as a technical reference for Perl 6 learners with a strong
Ruby background.


=head1 Basic Syntax

=head2 Statement Ending Semi-Colons

Ruby detects the end of most statements with a newline (and a few exceptions),
as long as the expression is complete. It is common break up a long expression
by leaving an operator dangling at the end of a line to ensure that the parsing
will continue:

=for code :lang<ruby>
    foo +     # In Ruby a trailing operator means parsing should continue
      bar +
      baz

In Perl 6 you must explicitly terminate statements with a C<;>, which allows
for better feedback and more flexibility in breaking up long lines. Two
exceptions not needing an explicit C<;> are the last statement in a block, and
after the closing curly brace of the block itself (if there is nothing else on
that line):

    my $x;
    ...;
    if 5 < $x < 10 {
      say "Yep!";
      $x = 17         # No ; required before closing }
    }                 # No ; required after closing } because of the newline
    say "Done!";      # The ; is not required here if nothing follows

=head2 Whitespace

Ruby allows a surprising amount of flexibility in the use of whitespace,
even with strict mode and warnings turned on:

=for code :lang<ruby>
    # unidiomatic but valid Ruby
    puts"Hello "+
    (people [ i]
        . name
        ) . upcase+"!"if$greeted[i]<1

Perl 6 also endorses programmer freedom and creativity, but balanced syntactic
flexibility against its design goal of having a consistent, deterministic,
extensible grammar that supports single-pass parsing and helpful error
messages, integrates features like custom operators cleanly, and doesn't lead
programmers to accidentally misstate their intent. Also, the practice of "code
golf" is slightly de-emphasized; Perl 6 is designed to be more concise in
concepts than in keystrokes.

As a result, there are various places in the syntax where whitespace is
optional in Ruby, but is either mandatory or forbidden in Perl 6. Many of those
restrictions are unlikely to concern much real-life Perl code (e.g. whitespace
being disallowed between an array variable and its square braces), but there
are a few that will unfortunately conflict with some Ruby hackers' habitual
coding styles:

=begin item
I<No space allowed before the opening parenthesis of an argument list.>

=begin code :skip-test
    foo (3, 4, 1); # Not right in Ruby or Perl 6 (in Perl 6 this would
                   # try to pass a single argument of type List to foo)
=end code

    foo(3, 4, 1);  # Ruby and Perl 6
    foo 3, 4, 1;   # Ruby and Perl 6 - alternative parentheses-less style

=end item

=begin item
I<Space is B<required> immediately after keywords>
=end item

=begin code :lang<ruby>
    if(a < 0); ...; end         # OK in Ruby
=end code
=begin code
    my $a; ...;
    if ($a < 0) { ... }         # Perl 6
    if $a < 0 { ... }           # Perl 6, more idiomatic
=end code

=begin code :lang<ruby>
    while(x > 5); ...; end      # OK in Ruby
=end code
=begin code
    my $x; ...;
    while ($x > 5) { ... }      # Perl 6
    while $x > 5 { ... }        # Perl 6, more idiomatic
=end code


=begin item
I<No space allowed before a postfix/postcircumfix operator (including
array/hash subscripts).>

    seen [ :fish ] = 1    # Ruby, not idiomatic but allowed
    %seen< fish > = 1;    # Perl 6, no space allowed after 'seen'
=end item

=begin item
I<Space required before an infix operator if it would
conflict with an existing postfix/postcircumfix operator.>

    n<1     # Ruby (in Perl 6 this would conflict with postcircumfix < >)
    $n < 1; # Perl 6

=end item

=head2 C«.» Method calls, C<.send>

Method call syntax uses a dot just like Ruby:

=for code :lang<ruby>
    person.name    # Ruby
=for code
    my $person; ...;
    $person.name   # Perl 6

To call a method whose name is not known until runtime:

=for code :lang<ruby>
    object.send(methodname, args);  # Ruby
=for code
    my $object; my Str $methodname; my @args; ...;
    $object."$methodname"(@args);   # Perl 6

If you leave out the quotes, then Perl 6 expects C<$methodname> to contain
a C<Method> object, rather than the simple string name of the method.

=head2 Variables, Sigils, Scope, and Common Types

In Ruby, variables use sigils primarily to indicate scope. C<$> for global
scope, C<@@> for class scope, C<@> for instance scope, and no sigil for local
variables (including parameters). The C<&> sigil is also used to indicate
method references. Symbols are prefixed with C<:>, but they are not variable
and so not really sigils.

In Perl 6 sigils are primarily used to indicate a role that the contained value
implements, indicating the type (or at least the interface) of the value. The
sigils are invariant, no matter how the variable is being used - you can think
of them as part of the variable's name.

The scope of a variable is instead indicated by the declaration itself (C<my>,
C<has>, C<our>, etc).

=head3 Variable Scope

For local variables, Ruby uses implicit variable declaration upon assignment
and limited to the current block. In Ruby the content of an C<if> or C<while>
built-in construct is not a block or scope.

Perl 6 uses explicit scope indicators, and never creates variables implicitly.
Every place you see C<{ ... }> is a scope, including the body of a conditional
or loop. The commonly used scope declarations:

=for code :lang<ruby>
    foo = 7        # Ruby, variable scope is defined by first assignment and
                   # extends to the end of the current block

=for code
    my  $foo = 7;   # Perl 6, lexical scoped to the current block
    our $foo = 7;   # Perl 6, package scoped
    has $!foo = 7;  # Perl 6, instance scoped (attribute)

=head3 C<$> Scalar

The C<$> sigil is always used with "scalar" variables (e.g. C<$name>). These
are single-value containers.

This is the most general-purpose variable type, with no restrictions on its
contents. Note that you can still address/use its contents, like C<$x[1]>,
C<$x{"foo"}>, and C<$f("foo")>.

=head3 C<@> Array

The C<@> sigil is always used with "array" variables (e.g. C<@months>,
C<@months[2]>, C<@months[2, 4]> for an array slice). Variables using the C<@>
sigil can only contain things that do the C<Positional> role, indicating
positional indexing and slicing capabilities.

=begin item
I<Indexing>

    puts months[2]; # Ruby
    say @months[2]; # Perl 6
=end item

=begin item
I<Value-slicing>

    puts months[8..11].join(',') # Ruby
    say @months[8..11].join(',') # Perl 6
=end item


=head3 C<%> Hash

The C<%> sigil is always used with "hash" variables (e.g. C<%calories>,
C<%calories<apple>>, C<%calories<pear plum>>). Variables using the C<%> sigil
can only contain things that do the C<Associative> role.

Ruby uses square brackets to access values for both Arrays and Hashes. Perl 6
uses curly braces for hashes instead. The angle-brackets version is available
which always autoquotes its contents (strings without quotes):

Adverbs can be used to control the type of slice.

=begin item
I<Indexing>

    puts calories["apple"]  # Ruby
    say %calories{"apple"}; # Perl 6

    puts calories["apple"]  # Ruby
    puts calories[:apple]   # Ruby, symbols for keys are common
    say %calories<apple>;   # Perl 6 - angle brackets instead of single-quotes
    say %calories«"$key"»;  # Perl 6 - double angles interpolate as double-quotes
=end item

=begin item
I<Value-slicing>

    puts calories.values_at('pear', 'plum').join(',') # Ruby
    puts calories.values_at(%w(pear plum)).join(',')  # Ruby, pretty?
    say %calories{'pear', 'plum'}.join(',');          # Perl 6
    say %calories<pear plum>.join(',');               # Perl 6 (prettier)
    my $keys = 'pear plum';
    say %calories«$keys».join(','); # Perl 6, interpolated split
=end item

=begin item
I<Key/value-slicing>

    say calories.slice('pear', 'plum').join(','); # Ruby, with ActiveRecord
    say %calories{'pear', 'plum'}:kv.join(',');   # Perl 6 - use :kv adverb
    say %calories<pear plum>:kv.join(',');        # Perl 6 (prettier version)
=end item

=head3 C<&> Sub

The C<&> sigil is used very similarly to Ruby's C<&> to refer to the function
object of a named subroutine/operator without invoking it, i.e. to use the name
as a "noun" instead of a "verb". Variables using the C<&> sigil can only
contain things that do the C<Callable> role.

=begin code :lang<ruby>
    add = -> n, m { n + m } # Ruby lambda for an addition function
    add.(2, 3)              # => 5, Ruby invocation of a lambda
    add.call(2, 3)          # => 5, Ruby invocation of a lambda
=end code

=begin code
    my &add = -> $n, $m { $n + $m }; # Perl 6 addition function
    &add(2, 3);                      # => 5, you can keep the sigil
    add(2, 3);                       # => 5, and it works without it
=end code

=for code :lang<ruby>
    foo_method = &foo;     # Ruby
=for code
    sub foo { ... };
    my &foo_method = &foo; # Perl 6

=for code :lang<ruby>
    some_func(&say) # Ruby pass a function reference
=for code
    sub some_func { ... };
    some_func(&say) # Perl 6 passes function references the same way

Often in Ruby we pass a block as the last parameter, which is especially used
for DSLs. This can be an implicit parameter called by C<yield>, or an explicit
block prefixed with C<&>. In Perl 6 a C<Callable> parameter is always listed
and called by the variable name (instead of yield), and there are a variety of
ways of invoking the function.

=begin code :lang<ruby>
    # Ruby, declare a method and call the implicit block argument
    def f
      yield 2
    end

    # Ruby, invoke f, pass it a block with 1 argument
    f do |n|
      puts "Hi #{n}"
    end
=end code

=begin code
    # Perl 6, declare a method with an explicit block argument
    sub f(&g:($)) {
      g(2)
    }

    # Perl 6, invoke f, pass it a block with 1 argument
    # There are several other ways to do this
    f(-> $n { say "Hi {$n}" }); # Explicit argument
    f -> $n { say "Hi {$n}" };  # Explicit argument, no parenthesis

    # Additionally, if 'f' is a method on instance 'obj' you can use C<:>
    # instead of parenthesis
    my $obj; ...;
    $obj.f(-> $n { say "Hi {$n}" });  # Explicit argument
    $obj.f: -> $n { say "Hi {$n}" };  # Explicit argument, no parenthesis
=end code

=head3 C<*> Slurpy params / argument expansion

In Ruby you can declare an argument to slurp the remainder of the passed
parameters into an array using a C<*> prefix. It works the same way in Perl 6:

=for code :lang<ruby>
    def foo(*args); puts "I got #{args.length} args!"; end # Ruby
=for code
    sub foo(*@args) { say "I got #{@args.elems} args!" }   # Perl 6

You might want to expand an array into a set of arguments. In Perl 6 this is
also done using C<*>:

=for code :lang<ruby>
    args = %w(a b c)         # Ruby
    foo(*args)

=for code
    sub foo($q, $r, $s) { ... };
    my @args = <a b c>;       # Perl 6
    foo(@*args);

Perl 6 has many more advanced ways of passing parameters and receiving
arguments, see L<Signatures|/language/functions#Signatures> and
L<Captures|/type/Capture>.

=head2 Twigils

Perl 6 additionally uses "twigils", which are further indicators about the
variable and go between the sigil and the rest of the variable name. Examples:

=begin code :skip-test
    $foo     # Scalar with no twigil
    $!foo    # Private instance variable
    $.foo    # Instance variable accessor
    $*foo    # Dynamically scoped variable
    $^foo    # A positional (placeholder) parameter to a block
    $:foo    # A named parameter
    $=foo    # POD (documentation) variables
    $?FILE   # Current source filename. The ? twigil indicates a compile-time value
    $~foo    # Sublanguage seen by parser, uncommon
=end code

Though each of these examples use the C<$> sigil, most could use C<@>
(Positional) or C<%> (Associative).

=head2 C<:> Symbols

Perl 6 generally uses strings in the places where Ruby uses symbols. A primary
example of this is in hash keys.

=for code :lang<ruby>
    address[:joe][:street] # Typical Ruby nested hash with symbol keys
=for code
    my %address; ...;
    %address<joe><street>  # Typical Perl 6 nested hash with string keys

Perl 6 has I<colon-pair> syntax, which can sometimes look like Ruby symbols.

=for code :lang<ruby>
    :age            # Ruby symbol

=begin code
    # All of these are equivalent for Perl 6
    :age            ;# Perl 6 pair with implicit True value
    :age(True)      ;# Perl 6 pair with explicit True value
    age => True     ;# Perl 6 pair using arrow notation
    "age" => True   ;# Perl 6 pair using arrow notation and explicit quotes
=end code

You could probably get away with using a colon-pair without an explicit value
and pretend that it is a Ruby symbol a lot of the time, but it isn't idiomatic
Perl 6.

=head1 Operators

Many operators have a similar usage in both Ruby and Perl 6:

=item C<,> List Separator
=item C<+> Numeric Addition
=item C<-> Numeric Subtraction
=item C<*> Numeric Multiplication
=item C</> Numeric Division
=item C<%> Numeric Modulus
=item C<**> Numeric Exponentiation
=item C<! && ||> Booleans, high-precedence
=item C<not and or> Booleans, low-precedence

You may use C<$x++> instead of C<x += 1> as a shortcut for incrementing a
variable. This can be used as a pre-increment C<++$x> (increment, return new
value) or post-increment C<$x++> (increment, return old value).

You may use C<$x--> instead of C<x -= 1> as a shortcut for decrementing a
variable. This can be used as a pre-decrement C<--$x> (decrement, return new
value) or post-decrement C<$x--> (decrement, return old value).

=head2 C«== != < > <= >=» Comparisons

Comparisons in Perl 6 are separated between numeric and string to avoid common
errors.

=item C«== != < > <= >=» Comparisons
=item C<eq ne lt gt le ge> String comparisons

For example, using C<==> tries to convert the values to numbers, and C<eq>
tries to convert the values to strings.

=head2 C«<=>» Three-way comparisons

In Ruby, the C«<=>» operator returns -1, 0, or 1.
In Perl 6, they return C<Order::Less>, C<Order::Same>, or C<Order::More>.

C«<=>» forces numeric context for the comparison.

C«leg» ("Less, Equal, or Greater?") forces string context for the comparison.

C«cmp» does either C«<=>» or C<leg>, depending on the existing type of its
arguments.

=head2 C<~~> Smart-match operator

This is a very common matching operator which doesn't exist in Ruby. Here are
some examples:

    my $foo; ...;
    say "match!" if $foo ~~ /bar/;       # Regex match
    say "match!" if $foo ~~ "bar";       # String match
    say "match!" if $foo ~~ :(Int, Str); # Signature match (destructure)

See L<S03/Smart matching|https://design.perl6.org/S03.html#Smart_matching>

=head2 C<& | ^> Numeric Bitwise ops
=head2 C<& | ^> Boolean ops

In Perl 6, these single-character ops have been removed, and replaced by
two-character ops which coerce their arguments to the needed context.

=begin code :skip-test
    # Infix ops (two arguments; one on each side of the op)
    +&  +|  +^  And Or Xor: Numeric
    ~&  ~|  ~^  And Or Xor: String
    ?&  ?|  ?^  And Or Xor: Boolean

    # Prefix ops (one argument, after the op)
    +^  Not: Numeric
    ~^  Not: String
    ?^  Not: Boolean (same as the ! op)
=end code

=head2 C<&.> Conditional chaining operator

Ruby uses the C<&.> operator to chain methods without raising an error if one
invocation returns nil. In Perl 6 use C<.?> for the same purpose.

=head2 C«<< >>» Numeric shift left, right ops, shovel operator

Replaced by C«+<» and C«+>» .

=for code :lang<ruby>
    puts 42 << 3  # Ruby
=for code
    say  42 +< 3; # Perl 6

Note that Ruby often uses the C«<<» operator as the "shovel operator", which is
similar to C<.push>. This usage isn't common in Perl 6.

=head2 C«=>» and C<:> Key-Value Separators

In Ruby, C«=>» is used in the context of key/value pairs for Hash literal
declaration and parameter passing. C<:> is used as a shorthand when the left
side is a symbol.

In Perl 6, C«=>» is the Pair operator, which is quite different in
principle, but works the same in many situations.

If you are using C«=>» in a hash literal, then the usage is very similar:

=for code :lang<ruby>
    hash = { "AAA" => 1, "BBB" => 2 }  # Ruby, though symbol keys are more common
=for code
    my %hash = ( AAA => 1, BBB => 2 ); # Perl 6, uses ()'s though {} usually work

=head2 C<? :> Ternary operator

In Perl 6, this is spelled with two question marks instead of one question
mark, and two exclamation points instead of one colon. This deviation from the
common ternary operators disambiguates several situations and makes the
false-case stand out more.

=for code :lang<ruby>
    result     = (  score > 60 )  ? 'Pass'  : 'Fail'; # Ruby
=for code
    my $score; ...;
    my $result = ( $score > 60 ) ?? 'Pass' !! 'Fail'; # Perl 6

=head2 C<+> String Concatenation

Replaced by the tilde. Mnemonic: think of "stitching" together the two strings with needle and thread.

=for code :lang<ruby>
    $food = 'grape' + 'fruit'  # Ruby
=for code
    my $food = 'grape' ~ 'fruit'; # Perl 6

=head2 String interpolation

In Ruby, C<"#{foo}s"> deliminates a block embedded in a double-quoted string.
In Perl 6 drop the C<#> prefix: C<"{$foo}s">. As in Ruby, you can place
arbitrary code into the embedded block and it will be rendered in string
context.

Simple variables can be interpolated into a double-quoted string without using the block syntax:

=begin code :lang<ruby>
    # Ruby
    name = "Bob"
    puts "Hello! My name is #{name}!"
=end code

=begin code :lang<ruby>
    # Perl 6
    my $name = "Bob";
    say "Hello! My name is $name!"
=end code

The result of an embedded block in Ruby uses C<.to_s> to get string context.
Perl 6 uses C<.Str>, or C<.gist> for the same affect.

=head1 Compound Statements

=head2 Conditionals

=head3 C<if> C<elsif> C<else> C<unless>

This work very similarly between Ruby and Perl 6, but Perl 6 uses C<{ }> to
clearly delineate the blocks.

=begin code :lang<ruby>
    # Ruby
    if x > 5
        puts "Bigger!"
    elsif x == 5
        puts "The same!"
    else
        puts "Smaller!"
    end
=end code

=begin code
    # Perl 6
    my $x; ...;
    if $x > 5 {
        say "Bigger!"
    } elsif $x == 5 {
        say "The same!"
    } else {
        say "Smaller!"
    }
=end code

Binding the conditional expression to a variable is a little different:

=for code :lang<ruby>
    if x = dostuff(); ...; end   # Ruby
=for code
    sub dostuff() {...};
    if dostuff() -> $x {...}     # Perl 6, block-assignment uses arrow

The C<unless> conditional only allows for a single block in Perl 6;
it does not allow for an C<elsif> or C<else> clause.

=head3 C<case>-C<when>

The Perl 6 C<given>-C<when> construct is like a chain of C<if>-C<elsif>-C<else>
statements or like the C<case>-C<when> construct in Ruby. A big difference is
that Ruby uses the C<==> comparison for each condition, but Perl 6 uses the
more general smart-match C<~~> operator.

It has the
general structure:

=begin code :lang<pseudo>
    given EXPR {
        when EXPR { ... }
        when EXPR { ... }
        default { ... }
    }
=end code

In its simplest form, the construct is as follows:

    my $value; ...;
    given $value {
        when "a match" {
            # do-something();
        }
        when "another match" {
            # do-something-else();
        }
        default {
            # do-default-thing();
        }
    }

This is simple in the sense that a scalar value is matched in the C<when>
statements. More generally, the matches are actually smart-matches on the
input value such that lookups using more complex entities such as regexps
can be used instead of scalar values.

=head2 Loops

=head3 C<while> C<until>

Mostly unchanged; parentheses around the conditions are optional, but if used, must
not immediately follow the keyword, or it will be taken as a function call
instead. Binding the conditional expression to a variable is also a little
different:

=for code :lang<ruby>
    while x = dostuff(); ...; end    # Ruby
=for code
    sub dostuff {...}; ...;
    while dostuff() -> $x {...}      # Perl 6

=head3 C<for> C<.each>

C<for> loops are rare in Ruby, instead we typically use C<.each> on an
enumerable. The most direct translation to Perl 6 would be to use C<.map> for
both C<.each> and C<.map>, but we typically use a C<for> loop directly.

=begin code :lang<ruby>
    # Ruby for loop
    for n in 0..5
        puts "n: #{n}"
    end

    # Ruby, more common usage of .each
    (0..5).each do |n|
        puts "n: #{n}"
    end
=end code

=begin code
    # Perl 6
    for 0..5 -> $n {
        say "n: $n";
    }

    # Perl 6, misusing .map
    (0..5).map: -> $n {
        say "n: $n";
    }
=end code

In Ruby, the iteration variable for C<.each> is a copy of the list element, and
modifying it does nothing to the original list. Note that it is a copy of the
REFERENCE, so you can still change the values to which it refers.

In Perl 6, that alias is read-only (for safety) and thus behaves exactly like
Ruby, unless you change C«->» to C«<->».

=for code :lang<ruby>
    cars.each { |car| ... }    # Ruby; read-only reference
=for code
    my @cars; ...;
    for @cars  -> $car   {...} # Perl 6; read-only
    for @cars <-> $car   {...} # Perl 6; read-write

=head2 Flow Interruption statements

Same as Ruby:

=item C<next>
=item C<redo>

=item2 C<break>

This is C<last> in Perl 6.

=head1 Regular Expressions ( Regex / Regexp )

Regular expressions in Perl 6 are significantly different, and more powerful,
than in Ruby. By default whitespace is ignored and all characters must be
escaped, for example. Regexes can be easily combined and declared in ways to
build efficient grammars.

There are many powerful features of Perl 6 regexes, especially defining entire
grammars using the same syntax. See L<Regexes|/language/regexes> and
L<Grammars|/language/grammars>.

=head2 C<.match> method and C<=~> operator

In Ruby, regex matches can be done against a variable using the C<=~> regexp
match operator or the C<.match> method. In Perl 6, the C<~~> smartmatch op is
used instead, or the C<.match> method.

=for code :lang<ruby>
    next if line   =~ /static/   # Ruby
    next if line  !~  /dynamic/; # Ruby
    next if line.match(/static/) # Ruby

=for code
    my $line; ...;
    next if $line  ~~ /static/;    # Perl 6
    next if $line !~~ /dynamic/ ;  # Perl 6
    next if $line.match(/static/); # Perl 6

Alternately, the C<.match> and C<.subst> methods can be used. Note that
C<.subst> is non-mutating. See
L<S05/Substitution|https://design.perl6.org/S05.html#Substitution>.

=head2 C<.sub> and C<.sub!>

In Perl 6 you typically use the C<s///> operator to do regex substitution.

=for code :lang<ruby>
    fixed = line.sub(/foo/, 'bar')        # Ruby, non-mutating
=for code
    my $line; ...;
    my $fixed = $line.subst(/foo/, 'bar') # Perl 6, non-mutating

=for code :lang<ruby>
    line.sub!(/foo/, 'bar')   # Ruby, mutating
=for code
    my $line; ...;
    $line ~~ s/foo/bar/;      # Perl 6, mutating

=head2 Regex options

Move any options from the end of the regex to the beginning. This may
require you to add the optional C<m> on a plain match like C«/abc/».

=for code :lang<ruby>
    next if $line =~    /static/i # Ruby
=for code
    my $line; ...;
    next if $line ~~ m:i/static/; # Perl 6

=head2 Whitespace is ignored, most things must be quoted

In order to aid in readability and reusability, whitespace is not significant
in Perl 6 regexes.

=for code :lang<ruby>
    /this is a test/ # Ruby, boring string
    /this.*/         # Ruby, possibly interesting string

=for code
    / this " " is " " a " " test /; # Perl 6, each space is quoted
    / "this is a test" /;           # Perl 6, quoting the whole string
    / this .* /;                    # Perl 6, possibly interesting string

=head2 Special matchers generally fall under the <> syntax

There are many cases of special matching syntax that Perl 6 regexes support.
They won't all be listed here, but often instead of being surrounded by C<()>,
the assertions will be surrounded by C«<>».

For character classes, this means that:

=item C<[abc]> becomes C«<[abc]>»

=item C<[^abc]> becomes C«<-[abc]>»

=item C<[a-zA-Z]> becomes C«<[a..zA..Z]>»

=item C<[[:upper:]]> becomes C«<:upper>»

=item C<[abc[:upper:]]> becomes C«<[abc]+:Upper>»

For look-around assertions:

=item C<(?=[abc])> becomes C«<?[abc]>»

=item C<(?=ar?bitrary* pattern)> becomes C«<before ar?bitrary* pattern>»

=item C<(?!=[abc])> becomes C«<![abc]>»

=item C<(?!=ar?bitrary* pattern)> becomes C«<!before ar?bitrary* pattern>»

=item C«(?<=ar?bitrary* pattern)» becomes C«<after ar?bitrary* pattern>»

=item C«(?<!ar?bitrary* pattern)» becomes C«<!after ar?bitrary* pattern>»

(Unrelated to <> syntax, the "lookaround" C</foo\Kbar/> becomes C«/foo <( bar )> /»

=item C<(?(?{condition))yes-pattern|no-pattern)> becomes C«[ <?{condition}>
      yes-pattern | no-pattern ]»

=head2 Longest token matching (LTM) displaces alternation

In Perl 6 regexes, C<|> does Longest Token Match (LTM), which decides which
alternation wins an ambiguous match based off of a set of rules, rather than
about which was written first in the regex.

To avoid the new logic, change any C<|> in your Ruby regex to a C<||>.

=head1 File-related operations

=head2 Reading the lines of a text file into an array

Both Ruby and Perl 6 make it easy to read all of the lines in a file into a
single variable, and in both cases each line has the newline removed.

=for code :lang<ruby>
    lines = File.readlines("file")   # Ruby
=for code
    my @lines = "file".IO.lines;     # Perl 6, create an IO object from a string

=head2 Iterating over the lines of a text file

Reading the entire file into memory isn't recommended. The C<.lines> method in
Perl 6 returns a lazy sequence, but assigning to an array forces the file to be
read. It is better to iterate over the results:

=begin code :lang<ruby>
    # Ruby
    File.foreach("file") do |line|
        puts line
    end
=end code

=begin code
    # Perl 6
    for "file".IO.lines -> $line {
        say $line
    }
=end code

=head1 Object Orientation

=head2 Basic classes, methods, attributes

Classes are defined similarly between Ruby and Perl 6, using the C<class>
keyword. Ruby uses C<def> for methods, whereas Perl 6 uses C<method>.

=begin code :lang<ruby>
    # Ruby
    class Foo
        def greet(name)
            puts "Hi #{name}!"
        end
    end
=end code

=begin code
    # Perl 6
    class Foo {
        method greet($name) {
            say "Hi $name!"
        }
    }
=end code

In Ruby you can use an attribute without declaring it beforehand, and you can
tell it is an attribute because of the C<@> sigil. You can also easily create
accessors using C<attr_accessor> and its variants. In Perl 6 you use a C<has>
declaration and a variety of sigils. You can use the C<!> twigil for private
attributes or C<.> to create an accessor.

=begin code :lang<ruby>
    # Ruby
    class Person
        attr_accessor :age    # Declare .age as an accessor method for @age
        def initialize
            @name = 'default' # Assign default value to private instance var
        end
    end
=end code

=begin code
    # Perl 6
    class Person {
        has $.age;              # Declare $!age and accessor methods
        has $!name = 'default'; # Assign default value to private instance var
    }
=end code

Creating a new instance of the class uses the C<.new> method. In Ruby you must
manually assign instance variables as needed inside C<initialize>. In Perl 6
you get a default constructor that accepts key/value pairs of accessor
attributes, and can do further setup in the C<BUILD> method. Like with Ruby,
you can override C<new> itself for more advanced functionality, but this is
rare.

=begin code :lang<ruby>
    # Ruby
    class Person
        attr_accessor :name, :age
        def initialize(attrs)
            @name = attrs[:name] || 'Jill'
            @age  = attrs[:age] || 42
            @birth_year = Time.now.year - @age
        end
    end
    p = Person.new( name: 'Jack', age: 23 )
=end code

=begin code
    # Perl 6
    class Person {
        has $.name = 'Jill';
        has $.age  = 42;
        has $!birth_year;
        method BUILD {
            $!birth_year = now.Date.year - $.age;
        }
    }
    my $p = Person.new( name => 'Jack', age => 23 )
=end code

=head2 Private Methods

Private methods in Perl 6 are declared with a C<!> prefixed in their name, and
are invoked with a C<!> instead of a C<.>.

=begin code :lang<ruby>
    # Ruby
    class Foo
        def visible
            puts "I can be seen!"
            hidden
        end

        private
        def hidden
            puts "I cannot easily be called!"
        end
    end
=end code

=begin code
    # Perl 6
    class Foo {
        method visible {
            say "I can be seen!";
            self!hidden;
        }

        method !hidden {
            say "I cannot easily be called!";
        }
    }
=end code

An important note is that in Ruby child objects can see parent private methods
(so they are more like "protected" methods in other languages). In Perl 6 child
objects cannot call parent private methods.

=head2 Going Meta

Here are a few examples of meta-programming. Note that Perl 6 separates the
meta-methods from the regular methods with a carat.

=for code :lang<ruby>
    # Ruby
    person = Person.new
    person.class
    person.methods
    person.instance_variables

=for code
    # Perl 6
    class Person {};
    ...
    my $person = Person.new;
    $person.^name;             # Perl 6, returns Person (class)
    $person.^methods;          # Perl 6, using .^ syntax to access meta-methods
    $person.^attributes;


Like Ruby, in Perl 6, everything is an object, but not all operations are
equivalent to C<.send>. Many operators are global functions that use typed
multi-dispatch (function signatures with types) to decide which implementation
to use.

=for code :lang<ruby>
    5.send(:+, 3)    # => 8, Ruby
=for code
    &[+](5, 3)       # => 8, Perl 6, reference to infix addition operator

    &[+].^candidates # Perl 6, lists all signatures for the + operator

See L<Meta-Object Protocol|/language/mop> for lots of further details.

=head1 Environment variables

=head2 Perl module library path

In Ruby, one of the environment variables to specify extra search paths for
modules is C<RUBYLIB>.

#for code :lang<shell>
    $ RUBYLIB="/some/module/lib" ruby program.rb

In Perl 6 this is similar, you merely needs to change the name. As you probably
guessed, you just need to use C<PERL6LIB>:

#for code :lang<shell>
    $ PERL6LIB="/some/module/lib" perl6 program.p6

As with Ruby, if you don't specify C<PERL6LIB>, you need to specify the
library path within the program via the C<use lib> pragma:

#for code :skip-test
    # Ruby and Perl 6
    use lib '/some/module/lib';

=head1 Misc.

=head2 Importing specific functions from a module

In Ruby there is no built-in way to selectively import/export methods from a
module.

In Perl 6 you specifies the functions which are to be exported by using the
C<is export> role on the relevant subs and I<all> subs with this role are
then exported. Hence, the following module C<Bar> exports the subs C<foo>
and C<bar> but not C<baz>:

=for code :skip-test
    unit module Bar; # remainder of the file is in module Bar { ... }

=for code :skip-test
    sub foo($a) is export { say "foo $a" }
    sub bar($b) is export { say "bar $b" }
    sub baz($z) { say "baz $z" }

To use this module, simply C<use Bar> and the functions C<foo> and C<bar>
will be available

=for code :skip-test
    use Bar;
    foo(1);    #=> "foo 1"
    bar(2);    #=> "bar 2"

If you tries to use C<baz> an "Undeclared routine" error is raised at compile time.

Some modules allow for selectively importing functions, which would look like:

=for code :skip-test
    use Bar <foo>; # Import only foo
    foo(1);        #=> "foo 1"
    bar(2);        # Error!

=head2 C<OptionParser>, parsing command-line flags

Command line argument switch parsing in Perl 6 is done by the parameter list of
the C<MAIN> subroutine.

=begin code :lang<ruby>
    # Ruby
    require 'optparse'
    options = {}
    OptionParser.new do |opts|
        opts.banner = 'Usage: example.rb --length=abc'
        opts.on("--length", "Set the file") do |length|
            raise "Length must be > 0" unless length.to_i > 0
            options[:length] = length
        end
        opts.on("--filename", "Set the file") do |filename|
            options[:file] = filename
        end
        opts.on("--verbose", "Increase verbosity") do |verbose|
            options[:verbose] = true
        end
    end.parse!

    puts options[:length]
    puts options[:filename]
    puts 'Verbosity ', (options[:verbose] ? 'on' : 'off')
=end code

=begin code :lang<shell>
    ruby example.rb --filename=foo --length=42 --verbose
        42
        foo
        Verbosity on

    ruby example.rb --length=abc
        Length must be > 0
=end code

=begin code
    # Perl 6
    sub MAIN ( Int :$length where * > 0, :$filename = 'file.dat', Bool :$verbose ) {
        say $length;
        say $filename;
        say 'Verbosity ', ($verbose ?? 'on' !! 'off');
    }
=end code

=begin code :lang<shell>
    perl6 example.p6 --file=foo --length=42 --verbose
        42
        foo
        Verbosity on
    perl6 example.p6 --length=abc
        Usage:
          example.p6 [--length=<Int>] [--file=<Any>] [--verbose]
=end code

Note that Perl 6 auto-generates a full usage message on error in
command-line parsing.

=head1 RubyGems, External Libraries

See L<https://modules.perl6.org/>, where a growing number of Perl 6 libraries
are available along with the tools to manage them.

If the module that you were using has not been converted to Perl 6, and no
alternative is listed in this document, then its use under Perl 6 may not
have been addressed yet.

You can experiment with L<Inline::Ruby|https://github.com/awwaiid/Inline-Ruby/>
to call existing Ruby code from your Perl 6 programs. This uses an embedded
instance of the C<ruby> interpreter to run Ruby code called from your Perl 6
script. Note that this is an EXPERIMENTAL library. You can similarly call other
language's libraries with Inline::Perl5, Inline::Python, and others.

=end pod

=begin comments

### Guidelines for contributions:

Headers should contain the text that a Ruby user might search for, since
those headings will be in the Table of Contents generated for the top of
the document.

We use POD =item instead of =head3 or =head4 for identical bits that need not
appear in the table of contents.

This article does not describe in detail language features that Ruby doesn't
have at all, instead referring to other documents.

Example code and links to other documents should be favored over long
explanations of details better found elsewhere.

Finally, if a real user asks a Ruby to Perl 6 question that is not being
answered here, please add it to the document. Even if we do not have a good
answer yet, that will be better than losing the information about a real need.

=end comments

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
